<template>
  <div class="sale">
    <v-data-table
      :headers="headers"
      :items="sales"
      :options.sync="options"
      :page.sync="pager.page"
      :items-per-page.sync="pager.pageSize"
      :server-items-length="pager.total"
      :loading="loading"
      @update:page="handlePage"
      @update:items-per-page="handlePageSize"
    >
      <template v-slot:top>
        <v-toolbar flat color="white">
          <v-toolbar-title>Sales</v-toolbar-title>
          <v-divider
            class="mx-4"
            inset
            vertical
          ></v-divider>
          <v-toolbar-items>
            <v-select
              :items="sortColumns"
              v-model="sortColumn"
              label="Sort By"
              item-text="name"
              item-value="column"
              class="mt-4"
              @change="handleSort"
              return-object
            ></v-select>
          </v-toolbar-items>

          <v-spacer></v-spacer>
          <v-dialog persistent v-model="dialog" max-width="640px">
            <template v-slot:activator="{ on }">
              <v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn>
            </template>
            <v-card>
              <v-card-title>
                <span class="headline">{{ formTitle }}</span>
              </v-card-title>
              <v-card-text>
                <v-container>
                  <v-form ref="editForm" v-model="valid">
                    <v-row>
                      <v-select
                        v-model="editedItem.product"
                        :items="products"
                        :hint="`${editedItem.product?editedItem.product.quantity:0} left`"
                        item-text="name"
                        item-value="id"
                        label="Product"
                        persistent-hint
                        return-object
                        single-line
                        :rules="rules.required"
                      ></v-select>
                    </v-row>
                    <v-row>
                      <v-col sm="6">
                        <v-text-field
                          v-model="editedItem.price"
                          type="number"
                          :rules="rules.number"
                          label="Price"
                        ></v-text-field>
                      </v-col>
                      <v-col sm="6">
                        <v-text-field
                          v-model="editedItem.quantity"
                          type="number"
                          :rules="quantityRules"
                          label="Number"
                        ></v-text-field>
                      </v-col>
                    </v-row>
                    <v-row>
                      <span>Total price: ${{editedItem.price * editedItem.quantity}}</span>
                    </v-row>
                  </v-form>
                </v-container>
              </v-card-text>
              <v-card-actions>
                <v-spacer></v-spacer>
                <v-btn color="blue darken-1" text @click="hideDialog">Cancel</v-btn>
                <v-btn color="blue darken-1" text :disabled="!valid" :loading="loading" @click="handleSave">Save</v-btn>
              </v-card-actions>
            </v-card>
          </v-dialog>
        </v-toolbar>
      </template>
      <template v-slot:item.salesDate="{item}">
        {{item.salesDate | moment('YYYY-MM-DD')}}
      </template>
      <template v-slot:item.user="{item}">
        {{item.user | nameOfUser}}
      </template>
      <template v-slot:item.product="{item}">
        {{item.product.name}}
      </template>
      <template v-slot:item.price="{item}">
        {{item.price.toFixed(2)}}
      </template>
      <template v-slot:item.totalPrice="{item}">
        {{item.totalPrice.toFixed(2)}}
      </template>
    </v-data-table>
  </div>
</template>

<script>
  import {getSale, getSales, addSale} from "../../../api/sale";
  import {getProducts} from "../../../api/product";

  export default {
    name: 'sale',
    data() {
      return {
        editedItem: {
          id: null,
          price: null,
          quantity: null,
          totalPrice: null,
          saleDate: null,
          user: null,
          product: null,
        },
        headers: [
          {text: '#', value: 'id', sortable: false},
          {text: 'Product', value: 'product', sortable: false},
          {text: 'Price', value: 'price', sortable: false},
          {text: 'Quantity', value: 'quantity', sortable: false},
          {text: 'Total', value: 'totalPrice', sortable: false},
          {text: 'Date', value: 'salesDate', sortable: false},
          {text: 'User', value: 'user', sortable: false},
        ],
        products: [],
        sales: [],
        sortColumns: [
          {name: 'Date', column: 'salesDate'},
          {name: 'Total Price', column: 'totalPrice'}
        ],
        sortColumn: {name: 'Date', column: 'salesDate'},
        loading: false,
        pager: {
          page: 1,
          pageSize: 15,
          total: 1,
          totalPages: 1,
        },
        options: {},
        valid: false,
        dialog: false,
        datePicker: false,
        formTitle: 'New Item',
        rules: {
          required: [v => !!v || 'Required'],
          number: [v => ~~v && v >= 0 || 'Must be greater than or equals to 0'],
        }
      }
    },
    computed: {
      quantityRules() {
        const rules = [];
        rules.push(...this.rules.required);
        rules.push(...this.rules.number);
        rules.push(v => !v || Math.floor(v).toString() === v.toString() || 'Field must be an integer');
        if (this.editedItem.product) {
          const rule = v => v <= this.editedItem.product.quantity || 'Out of stock';
          rules.push(rule);
        }
        return rules;
      }
    },
    methods: {
      handleSort() {
        this.pager.page = 1;
        this.pager.total = 0;
        this.pager.totalPages = 0;
        this.loadSales();
      },
      handlePage(page) {
        this.pager.page = page;
        this.loadSales();
      },
      handlePageSize(size) {
        if (size === -1) {
          this.$toasted.error('Page size cannot be "All"');
          this.pager.pageSize = 15;
        }
        else {
          this.pager.pageSize = size;
          this.loadSales();
        }
      },
      resetItem() {
        Object.keys(this.editedItem).forEach(k => this.editedItem[k] = null);
      },
      hideDialog() {
        this.$refs['editForm'].reset();
        this.dialog = false;
        this.resetItem();
        this.formTitle = 'New Item';
      },
      editItem(id) {
        getSale(id).subscribe(res => {
          if (res.data) {
            Object.keys(this.editedItem).forEach(k => this.editedItem[k] = res.data[k]);
            this.dialog = true;
            this.formTitle = 'Edit'
          }
        })
      },
      handleSave() {
        if (!this.editedItem.id) this.handleAdd();
      },
      handleAdd() {
        if (!this.editedItem.id) {
          this.loading = true;
          addSale(this.editedItem).subscribe(res => {
            if (res.data) {
              this.$toasted.info('Record added');
              this.loadSales();
              this.loadProducts();
              this.hideDialog();
            }
            else {
              this.$toasted.error('No response');
            }
          }, err => {
            this.$toasted.error(err);
            this.loading = false;
          })
        }
      },
      loadSales() {
        this.loading = true;
        const {page, pageSize} = this.pager;
        getSales(page, pageSize, this.sortColumn.column).subscribe(res => {
          // console.log(res);
          if (res.data) {
            const {current, data, pageSize, total, totalPages} = res.data;
            this.pager.pageSize = pageSize;
            this.pager.page = current;
            this.pager.total = total;
            this.pager.totalPages = totalPages;
            this.sales = data;
          }
          this.loading = false;
        }, err => {
          this.$toasted.error(err);
          this.loading = false;
        })
      },
      loadProducts() {
        getProducts(1, 1000).subscribe(res => {
          // console.log(res.data);
          if (res.data) {
            const {data} = res.data;
            this.products = data;
          }
        })
      }
    },
    mounted() {
      this.loadProducts();
      this.loadSales();
    }
  };
</script>
